package com.ctfo.ulcp.exp.utils;


import lombok.extern.slf4j.Slf4j;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.MapListHandler;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
public abstract class JdbcService implements AutoCloseable {

    final Connection connection;
    final String schema;

    public JdbcService(String url, String user, String password) throws SQLException {
        this.connection = DriverManager.getConnection(url, user, password);
        this.schema = getDatabaseNameFromJdbcUrl(url);
    }

    public abstract List<TableInfo> fetchTableInfoList() throws SQLException;

    abstract Map<String, Object> fetchSampleData(String table) throws SQLException;


    public List<TableInfo> fetchTableInfoListWithSample() throws SQLException {
        List<TableInfo> tables = fetchTableInfoList();
        for (TableInfo table : tables) {
            Map<String, Object> sampleData = fetchSampleData(table.name());
            if (sampleData != null) {
                table.columns().forEach(c -> {
                            // 二进制数据不显示示例数据
                            if (!c.getType().toLowerCase().contains("lob")) {
                                c.setSampleData(sampleData.get(c.getName()));
                            }
                        }
                );
            }
        }
        return tables;
    }


    public List<Map<String, Object>> executeQuery(String sql) throws SQLException {
        long start = System.currentTimeMillis();
        QueryRunner runner = new QueryRunner();
        List<Map<String, Object>> results = runner.query(connection, sql, new MapListHandler());

        log.debug("executeQuery:{}, result count:{}, time:{}ms", sql, results.size(), System.currentTimeMillis() - start);
        return results;
    }


    @Override
    public void close() throws SQLException {
        connection.close();
    }


    private static String getDatabaseNameFromJdbcUrl(String jdbcUrl) {
        Pattern pattern = Pattern.compile("jdbc:\\w+://[^/]+/([\\w-]+)");
        Matcher matcher = pattern.matcher(jdbcUrl);
        if (matcher.find()) {
            return matcher.group(1);
        }
        throw new RuntimeException("invalid jdbcUrl:" + jdbcUrl);
    }


}
